package record

import (
	"bytes"
	"sync"

	"github.com/google/btree"
)

type IndexValue struct {
	FileId    uint32
	ValueSize uint64
	ValuePos  uint32
	TimeStamp uint64
}

func NewIndexValue() *IndexValue {
	return &IndexValue{}
}

func NewIndexValueWithFiled(fileId uint32, valueSize uint64, valuePos uint32, timeStamp uint64) *IndexValue {
	return &IndexValue{
		FileId:    fileId,
		ValueSize: valueSize,
		ValuePos:  valuePos,
		TimeStamp: timeStamp,
	}
}

type Item struct {
	Key   []byte
	Value *IndexValue
}

func (i *Item) Less(bi btree.Item) bool {
	return bytes.Compare(i.Key, bi.(*Item).Key) == -1
}

type BTree struct {
	tree *btree.BTree
	lock *sync.RWMutex
}

func NewBtree() *BTree {
	return &BTree{
		tree: btree.New(32),
		lock: new(sync.RWMutex),
	}
}

func (bt *BTree) Put(key []byte, value *IndexValue) bool {
	item := &Item{
		Key:   key,
		Value: value,
	}
	bt.lock.Lock()
	defer bt.lock.Unlock()
	bt.tree.ReplaceOrInsert(item)
	return true
}

func (bt *BTree) Get(key []byte) *IndexValue {
	bt.lock.Lock()
	defer bt.lock.Unlock()

	k := &Item{Key: key}
	item := bt.tree.Get(k)
	if item == nil {
		return nil
	}
	return item.(*Item).Value
}

func (bt *BTree) Delete(key []byte) bool {
	bt.lock.Lock()
	defer bt.lock.Unlock()

	k := &Item{Key: key}
	bt.tree.Delete(k)
	return true
}
